JDBC事务|JDBC编程

    在jdbc编程中,事务是手动提交的,spring接管事务后,整个流程被透明化的东西很多,作为编程人员是应该了解什么被透明化了,不然无法了解事情的本质。

    事务处理一定程度上和数据库实现相关,数据库有个autocommit属性,一般而言,MySQL默认开启,Oracle默认关闭,另外autocommit属性分为全局和会话级别,全局级别影响的是所有会话,单个会话级别只针对当前会话生效,这个属性的设置影响到了jdbc事务编程的方式,因为在自动提交模式下,任何一个语句都会作为一个单独事务立马提交,这样编程人员无法将多条语句作为一个事务统一提交,所以,在jdbc编程中,一般模式是将autocommit首先设置为false,然后开始手动事务,大致伪代码如下:

try {
	conn.setAutoCommit(false);
	stmt = conn.createStatement();
	// TODO 事务需要包括的多条操作
	conn.commit();
} catch (Exception e) {
	e.printStackTrace();
	conn.rollback();
} finally {
	// 3.关闭连接,该步骤最好放在finally代码块中,这样可以确保关闭链接的操作执行了
	if (stmt != null)
		stmt.close();
	if (conn != null)
		conn.close();
}

这里有个小小的区别需要看到,就是JDBC的API中是没有形如startTransaction(),beginTransaction()之类的API的,为什么?因为setAutoCommit(false)就起到了这个作用,所以,就不需要类似开启事务的API了,换句话说,如果其他框架提供了类型开始事务的API,很可能就说明这个API的功能就是禁止自动提交之类的功能。还有一点,我们还要关注数据库本身提供的API,以MySQL为例,MySQL本身就是提供设置autocommit值,以及START TRANSACTION/BEGIN这两个命令来开启事务,他们是有作用关系的,START TRANSACTION有禁用autocommit的功能,所以现在能理解为什么会同时有这两种方式来开启事务了吧,START TRANSACTION是能够在autocommit为true的情况下开启事务的。这里的几个步骤基本上是必须的步骤,特别要关注的的就是不要把autocommit特性忘了,这个在spring中也可以验证:

org.springframework.jdbc.datasource.DataSourceTransactionManager中doBegin()方法中有这么一段代码

// Switch to manual commit if necessary. This is very expensive in some JDBC drivers,
// so we don't want to do it unnecessarily (for example if we've explicitly
// configured the connection pool to set it already).
if (con.getAutoCommit()) {
	txObject.setMustRestoreAutoCommit(true);
	if (logger.isDebugEnabled()) {
		logger.debug("Switching JDBC Connection [" + con + "] to manual commit");
	}
	con.setAutoCommit(false);
}

从这里还可以看出,切到手动提交在某些jdbc驱动下是个昂贵的操作,所以没有必要去做无谓的切换,另外,在使用了连接池后,autocommit属性是可以通过连接池配置的,所以在使用时一定要清楚的知道自己使用的各个组件框架的特性,以及他们是否适当的配置了相关的属性。
下面我们讲讲JDBC编程的一些规则:

猜你喜欢

转载自blog.csdn.net/tales522/article/details/80958944