首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >用JDBC和c3p0对MySQL DB进行多线程写入

用JDBC和c3p0对MySQL DB进行多线程写入
EN

Stack Overflow用户
提问于 2016-06-13 11:37:10
回答 2查看 588关注 0票数 2

我编写了一个DAO类,它允许ExecutorServices调用的多个线程写入MySQL DB。

编辑:--我正在使用c3p0创建一个JDBC。因此,每个新线程都将通过调用

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
DataBaseManager.getInstance().getConnection()

在执行时似乎存在随机并发问题,例如:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
java.sql.SQLException: No value specified for parameter 1
at com.eanurag.dao.DataBaseManager.writeData(DataBaseManager.java:102)

我无法理解代码的所有问题。我应该同步整个writeData()吗?

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public class DataBaseManager {

    private final static Logger logger = Logger.getLogger(DataBaseManager.class);

    private static volatile DataBaseManager dbInstance = null;

    private DataBaseManager() {
        cpds = new ComboPooledDataSource();
        try {
            cpds.setDriverClass("com.mysql.jdbc.Driver");
        } catch (PropertyVetoException e) {
            logger.error("Error in Initializing DB Driver class", e);
        }
        cpds.setJdbcUrl("jdbc:mysql://" + DB_HOST + "/" + DB_NAME);
        cpds.setUser(DB_USER);
        cpds.setPassword(DB_PASS);

        cpds.setMinPoolSize(MINIMUM_POOL_SIZE);
        cpds.setAcquireIncrement(INCREMENT_SIZE);
        cpds.setMaxPoolSize(MAXIMUM_POOL_SIZE);
        cpds.setMaxStatements(MAX_STATEMENTS);
    }

    public static DataBaseManager getInstance() {
        if (dbInstance == null) {
            synchronized (WorkerManager.class) {
                if (dbInstance == null) {
                    dbInstance = new DataBaseManager();
                }
            }
        }

        return dbInstance;
    }

    private ComboPooledDataSource cpds;

    private static final Integer MINIMUM_POOL_SIZE = 10;
    private static final Integer MAXIMUM_POOL_SIZE = 1000;
    private static final Integer INCREMENT_SIZE = 5;
    private static final Integer MAX_STATEMENTS = 200;

    private volatile Connection connection = null;
    private volatile Statement statement = null;
    private volatile PreparedStatement preparedStatement = null;

    private static final String DB_HOST = "localhost";
    private static final String DB_PORT = "3306";
    private static final String DB_USER = "root";
    private static final String DB_PASS = "";
    private static final String DB_NAME = "crawly";
    private static final String URL_TABLE = "url";


    public Connection getConnection() throws SQLException {
        logger.info("Creating connection to DB!");
        return this.cpds.getConnection();
    }

    public Boolean writeData(URL url) {
        StringBuffer writeDBStatement = new StringBuffer();
        writeDBStatement.append("insert into");
        writeDBStatement.append(" ");
        writeDBStatement.append(DB_NAME);
        writeDBStatement.append(".");
        writeDBStatement.append(URL_TABLE);
        writeDBStatement.append(" ");
        writeDBStatement.append("values (?,?,default)");

        Boolean dbWriteResult = false;

        try {
            connection = DataBaseManager.getInstance().getConnection();

                preparedStatement = connection.prepareStatement(writeDBStatement.toString());
                preparedStatement.setString(1, url.getURL());
                preparedStatement.setString(2, String.valueOf(url.hashCode()));
                dbWriteResult = (preparedStatement.executeUpdate() == 1) ? true : false;


            if(dbWriteResult){
                logger.info("Successfully written to DB!");
            }
        } catch (SQLException e) {
            logger.error("Error in writing to DB", e);
        } finally {
            try {
                preparedStatement.close();
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        return dbWriteResult;
    }


}
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-06-13 11:52:25

这里发生了什么事?

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public Connection getConnection() throws SQLException {
    logger.info("Creating connection to DB!");
    return this.cpds.getConnection();
}

也就是说,cpds.getConnection()是做什么的?当你打电话:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
connection = DataBaseManager.getInstance().getConnection();

在这里,连接对象是应该是单例类的一个成员,但是对writeData()的每次调用都会用一个新的getConnection()调用覆盖它。getConnection()调用线程也不安全吗?

另外,为什么连接对象被声明为类成员,然后在每次调用writeData()时重写?在多线程环境中,存在的代码允许连接对象在调用getConnection()之前被另一个prepareStatement()调用覆盖,因为对writeData()的访问没有锁定。preparedStatement也一样。将它们移到writeData()方法中。

票数 2
EN

Stack Overflow用户

发布于 2016-06-13 12:02:56

connectionpreparedStatement变量必须是本地变量,而不是实例成员。

不需要同步。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/37797840

复制
相关文章
JAVA中字符串和数组做参数传递的情况
首先明确的一点就是在java中只有值传递!只有值传递!理论依据来自《think in java》。接下来就是具体说明为何java只有值传递。 因为java中有基本类型和引用类型两种数据类型,再加上String这个特殊的类型,所以主要从三个方面就行解释。
全栈程序员站长
2022/08/23
1.5K0
JAVA中字符串和数组做参数传递的情况
如何理解“正数的补码是其本身”
补数,也叫补码,有“1的补数”和“2的补数”之分,前者多称为“反码”,后者干脆就直接叫“补码”。
袁承兴
2021/01/05
2.6K0
学习本身不难,难得是了解该学哪些!
先说明,本文说的是技术架构,而不是业务架构,另外,这个架构是指目前比较热门的高并发大数据的架构。论能力,我还达不到架构师的水平,所以我目前还在不断努力。
用户5224393
2019/10/29
3570
学习本身不难,难得是了解该学哪些!
Spring Batch 配置一个步骤(Step)
如我们在 域语言(Domain Language)章节中讨论的内容一致,一个 步骤(Step)是一个独立封装了执行顺序的批量作业(Job),并且包含有用于定义和控制一个批量作业的所有独立信息。
HoneyMoose
2020/02/24
4770
什么是行为驱动的 Python?
您是否听说过 行为驱动开发(behavior-driven development)(BDD),并好奇这是个什么东西?也许你发现了团队成员在谈论“嫩瓜”(LCTT 译注:“ 嫩瓜(gherkin)” 是一种简单的英语文本语言,工具 cucumber 通过解释它来执行测试脚本,见下文),而你却不知所云。或许你是一个 Python 人(Pythonista),正在寻找更好的方法来测试你的代码。 无论在什么情况下,了解 BDD 都可以帮助您和您的团队实现更好的协作和测试自动化,而 Python 的 behave 框架是一个很好的起点。
用户8639654
2021/10/25
1.7K0
Guava字符串的处理
一步将字符串转为List<Long>集合(前面先转为list<String>,后面用java8特性将List<String>转为List<Long>)
诺浅
2020/08/20
7220
Shell的字符串处理
在Shell编程快速入门指南一文中已经简单介绍了字符串的变量命名、截取、获取长度等操作,但通常我们对字符串的操作的需求远远不止这些,Shell本身一起已经内置了一些对字符串的操作。
用户1515472
2019/07/24
6460
一个专业处理字符串的IDEA插件
字符串处理想必是小伙伴们平时开发时经常碰到的一个 “难题”。为什么要打上引号?因为你说他难吧,其实也不是什么特别复杂的事;你说他不难吧,弄起来还真挺麻烦的,像删除其中空行啊、切换大小写啊,都是基础的操作,但是有时候就是会让人心情毛躁。
程序猿DD
2021/12/08
7780
一个专业处理字符串的IDEA插件
一个处理字符串的工具类StringEscapeUtils
最近有用到一个字符串处理类StringEscapeUtils,来自于apache工具包common-lang中,,这个类能很方便的进行html,xml,java等的转义与反转义;
JQ实验室
2022/10/30
2K0
Spring Batch 配置一个步骤(Step)
如我们在 域语言(Domain Language)章节中讨论的内容一致,一个 步骤(Step)是一个独立封装了执行顺序的批量作业(Job),并且包含有用于定义和控制一个批量作业的所有独立信息。
HoneyMoose
2020/02/25
6680
Spring Batch 配置一个步骤(Step)
有一个列表,希望字符串中出现这个列表中任何一个元素的话就输出 去掉该元素后的字符串
前几天在Python钻石群有个叫【盼头】的粉丝问了一个关于Python列表处理的问题,这里拿出来给大家分享下,一起学习。
前端皮皮
2022/08/17
1.9K0
有一个列表,希望字符串中出现这个列表中任何一个元素的话就输出 去掉该元素后的字符串
c字符串截取一部分字符串_截取指定字符串
当然可以自己写一个匹配字符串获取计数的函数配合使用,任何代码都是根据需求来定制的。
全栈程序员站长
2022/11/08
6750
Mysql中varchar字符串的比较,swoole预处理参数绑定
类似select * from sheets where s_status > 3
宣言言言
2019/12/15
1.5K0
基于 BDD 理论的 Nebula 集成测试框架重构(下篇)
在上篇文章中,我们介绍了 Nebula Graph 的集成测试的演进过程。本篇就介绍一下向测试集合中添加一个用例,并成功运行所有的测试用例的过程。
NebulaGraph
2021/06/30
8800
基于 BDD 理论的 Nebula 集成测试框架重构(下篇)
开发获取`NSURL`字符串的参数
因为今天要获取返回的CallBack返回URL字符串后拼接的字符串 发现NSURL这个类里面没有什么API可以获取。我相信这个经常用到的东西苹果没有提供对应的接口或者方法,让开发者自己解析,这不像苹果的风格。我就顺着NSURL所在的文件向下面找去。
君赏
2018/08/31
1.6K0
开发获取`NSURL`字符串的参数
如何高效使用Gherkin
时间回到2022年,我参与了一个使用了Flutter技术构建的Web前端项目。在这个项目上,我们小组的目标是实施Flutter前端自动化测试。
ThoughtWorks
2023/09/18
3370
如何高效使用Gherkin
C#字符串为空的几种情况
我们知道,在C#中,string是引用类型的。为空情况有以下三种: 1、  string str1="":会定义指针(栈),并在内存里划一块值为空的存储空间(堆),指针指向这个空间。 2、String str2=String.Empty:同上。但是这是个静态方法,不会反复的重复申请内存,要优于1中的方式。 3、String str3=null:只定义了一个引用(栈),没有指向任何地方,也未在堆上分配存储空间。在使用前如果不实例化的话,将报错。 知道了string的几种空类型的区别,那么我们怎么来判断一个字符
小端
2018/04/16
2K0
字符串处理
在name.title()中,name后面的点(.)让Python对变量name执行title()指定的操作。每个方法后面都跟着一对括号,这是因为方法通常需要额外的信息来完成其工作。将字符串改为全部大写或全部小写可以用:
狼啸风云
2019/01/18
7580
浅谈Python如何处理字符串
本次内容是以以Python 2.7为例来进行讨论的,Python 3x与其类似。 1. Python文件编码 在文件头部一般声明为UTF-8: # encoding=utf8 有的也声明为GBK,多见于Windows系统上 2. 常用字符串操作 s = 'I love python ' rs = s[::-1] # 反转字符串,rs为:' nohtyp evol I' s[0] # 取s的第0个字符‘I' s[-2] # 去s的倒数第二个字符'n', (负索引,倒数) s[0:3] #去s的第0-3个字
昱良
2018/04/04
7380
字符串处理中的通配符
通配符,从名称上我们也能大概猜到,这种特殊的符号是有通用匹配功能的,也就是可以匹配所有的符号。
xyj
2020/07/28
2.2K0
字符串处理中的通配符

相似问题

如何处理在“然后”阶段有许多步骤的gherkin场景

20

替换Gherkin参数字符串

34

如何用步骤定义函数中的字符串列表代替gherkin特征文件中的参数数

10

Gherkin嵌套步骤意义

10

Python - Gherkin步骤转换

10
添加站长 进交流群

领取专属 10元无门槛券

AI混元助手 在线答疑

扫码加入开发者社群
关注 腾讯云开发者公众号

洞察 腾讯核心技术

剖析业界实践案例

扫码关注腾讯云开发者公众号
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文