事务管理---编程式事务管理和申明式事务管理区别(一)

本贴最后更新于 3766 天前,其中的信息可能已经时移俗易

前言:

       近期在做项目的时候,发现有很多bug是因为spring的事务问题引起。究其原因主要是项目组人员对事务的掌握程度不一导致。接下来试着写几篇博客站在我理解的角度上将这些问题解释清楚。

编程式事务管理:

      简单来说,编程式事务管理是需要我们在代码中手动的开启事务,关闭事务,提交,回滚更加的细粒度。对应方法有beginTransaction()、commit()、rollback()、closeTransaction()等一系列方法。

以上针对的是jdbc没有被任何框架封装的操作。这些基础的增删改查,相信我们在初学数据库操作都做过。类似代码如下:

	/**
	 * 开始事务
	 * @param cnn
	 */
	public static void beginTransaction(Connection cnn){
		if(cnn!=null){
			try {
				if(cnn.getAutoCommit()){
					cnn.setAutoCommit(false);
				}
			} catch (SQLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}
/**
 * 提交事务
 * @param cnn
 */
public static void commitTransaction(Connection cnn){
	if(cnn!=null){
		try {
			if(!cnn.getAutoCommit()){
				cnn.commit();
			}
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}

/**
 * 回滚事务
 * @param cnn
 */
public static void rollBackTransaction(Connection cnn){
	if(cnn!=null){
		try {
			if(!cnn.getAutoCommit()){
				cnn.rollback();
			}
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}

这种方式,我们利用了原生的jdbc方法。但是我们如果调用spring封装的底层api方法,则需要配置一番。

public class BankServiceImpl implements BankService {
private BankDao bankDao;
private TransactionDefinition txDefinition;
private PlatformTransactionManager txManager;
......
public boolean transfer(Long fromId, Long toId, double amount) {
TransactionStatus txStatus = txManager.getTransaction(txDefinition);
boolean result = false;
try {
     result = bankDao.transfer(fromId, toId, amount);
     txManager.commit(txStatus);
} catch (Exception e) {
     result = false;
     txManager.rollback(txStatus);
     System.out.println("Transfer Error!");
    }
    return result;
 }
}
<bean id="bankService" class="footmark.spring.core.tx.programmatic.origin.BankServiceImpl">
<property name="bankDao" ref="bankDao"/>
<property name="txManager" ref="transactionManager"/>
<property name="txDefinition">
<bean class="org.springframework.transaction.support.DefaultTransactionDefinition">
<property name="propagationBehaviorName" value="PROPAGATION_REQUIRED"/>
</bean>
</property>
</bean>

申明式事务管理:

       主要通过spring的aop的方式,通过注解,或者配置文件。对方法前后加上事务控制,是属于粗粒度的。示例如下

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
 "http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
&lt;bean id=&quot;sqlMapClient&quot; class=&quot;org.springframework.orm.ibatis.SqlMapClientFactoryBean&quot;&gt;
	&lt;property name=&quot;configLocation&quot;&gt;
		&lt;value&gt;classpath:sqlmap-config.xml&lt;/value&gt;
	&lt;/property&gt;
	&lt;property name=&quot;dataSource&quot; ref=&quot;dataSource&quot; /&gt;
&lt;/bean&gt;

&lt;!-- feng.tan --&gt;
&lt;bean id=&quot;sqlMapClientTemplate&quot; class=&quot;org.springframework.orm.ibatis.SqlMapClientTemplate&quot;&gt;
	&lt;property name=&quot;sqlMapClient&quot;&gt;
		&lt;ref bean=&quot;sqlMapClient&quot; /&gt;
	&lt;/property&gt;
&lt;/bean&gt;

&lt;bean id=&quot;transactionInterceptor&quot;
	class=&quot;org.springframework.transaction.interceptor.TransactionInterceptor&quot;&gt;
	&lt;property name=&quot;transactionManager&quot;&gt;
		&lt;ref bean=&quot;transactionManager&quot; /&gt;
	&lt;/property&gt;
    &lt;property name=&quot;transactionAttributes&quot;&gt;
     &lt;props&gt;
      &lt;prop key=&quot;remove*&quot;&gt;PROPAGATION_REQUIRED&lt;/prop&gt;
      &lt;prop key=&quot;add*&quot;&gt;PROPAGATION_REQUIRED&lt;/prop&gt;
      &lt;prop key=&quot;modify*&quot;&gt;PROPAGATION_REQUIRED&lt;/prop&gt;
      &lt;prop key=&quot;update*&quot;&gt;PROPAGATION_REQUIRED&lt;/prop&gt;
      &lt;prop key=&quot;find*&quot;&gt;PROPAGATION_REQUIRED,readOnly&lt;/prop&gt;
     &lt;/props&gt;
    &lt;/property&gt;
&lt;/bean&gt;
&lt;!-- 自动代理 --&gt;
&lt;bean id=&quot;autoproxy&quot;
	class=&quot;org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator&quot;&gt;
	&lt;property name=&quot;beanNames&quot;&gt;
		&lt;list&gt;
			&lt;value&gt;*Service&lt;/value&gt;
		&lt;/list&gt;
	&lt;/property&gt;
	&lt;property name=&quot;interceptorNames&quot;&gt;
		&lt;list&gt;
			&lt;value&gt;transactionInterceptor&lt;/value&gt;
		&lt;/list&gt;
	&lt;/property&gt;
&lt;/bean&gt;

</beans>

上面的xml是我实际项目中的配置文件。采用自动代理的方式给service层的方法符合条件的加上了事务控制。

参考资料:http://www.ibm.com/developerworks/cn/education/opensource/os-cn-spring-trans/section4.html

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...