Jboss下使用spring配置实现JTA全局事务管理(上)

引言:

事务(Transaction)的实现能够保证一系列数据库等操作的原子性,即要么全部都成功,要么全部都失败。保证ACID特性在许多项目中尤其是联机交易、银行、电商等项目显得尤为重要。最近因项目要求,对事务进一步学习,以下是个人一些理解及部分代码。欢迎不吝赐教、指正。

单数据源事务:

1.JDBC事务
部分项目JDBC事务是通过代码层面实现,代码层面管理数据库连接,获取connection后,设置setAutoCommit属性为false,一系列数据库操作之后,使用connection进行commit操作,如果catch到exception,则rollback。以此来实现一系列数据库操作的原子性。一般代码如下:
               PreparedStatement pstmt = null;
		try {
			conn.setAutoCommit(false);
			String sql = "insert into XXtable (colum1, colum2) values(val1, val2)";
			pstmt = (PreparedStatement) conn.prepareStatement(sql);
			pstmt.execute();
			String sql2 = "";
			//.......其他数据库操作
			conn.commit();
		} catch (Exception e) {
			conn.rollback();
			pstmt.close();
			conn.close();
		}
这种最简单的事务实现demo,代码层面自行管理事务,容易有坑。

2.spring管理事务
大部分项目由spring托管实现(还有EJB君),spring有简单好用的完善的事务管理机制。通过spring.xml配置加service层注解,就能实现sping事务管理。
spring实现又包含引入以hibernate为例等ORM包的实现(org.springframework.orm.hibernate3.HibernateTransactionManager)和 jdbc的包(org.springframework.jdbc.datasource.DataSourceTransactionManager)等,小老弟认为具体实现看项目实际需要。
下面简单介绍两种实现,主要贴出配置文件。

spring配置数据源时主要包含两种方式,一是项目配置中管理数据源连接池;另一是使用jndi方式,依赖应用服务器管理数据源连接池。在此不赘述两种方式优劣,还是看实际需要。如下:

1)c3p0 + jdbc 

c3p0连接池,连接内容在项目配置文件中
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"
		destroy-method="close">
		<property name="driverClass" value="com.mysql.jdbc.Driver"></property>
		<property name="jdbcUrl" value="jdbc:mysql://IP:port/database"></property>
		<property name="user" value="user"></property>
		<property name="password" value="password"></property>
		<property name="maxPoolSize" value="***"></property>
		<property name="minPoolSize" value="***"></property>
	</bean>

	<bean id="proxyDataSource"
		class="org.springframework.jdbc.datasource.TransactionAwareDataSourceProxy">
		<constructor-arg>
			<ref bean="dataSource" />
		</constructor-arg>
	</bean>

	<bean id="transactionManager"
		class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
		<property name="dataSource" ref="proxyDataSource" />
	</bean>

引入数据源后,记得添加事务驱动:
    <tx:annotation-driven transaction-manager="transactionManager" />
特别注意,需要在dataSource属性中加上配置
    <property name="autoCommitOnClose" value="false" />

该种实现方式一般用于 jdbc、dbutils、spring jdbctemplate 等数据库操作中。
2) hibernate + jndi + c3p0
以下配置为数据源引入及hibernate 、sessionFactory相关属性配置:

   <bean id="dataSourceMgm" class="org.springframework.jndi.JndiObjectFactoryBean">
        <property name="jndiName">
            <value>java:/jdbc/mgmdb</value>
        </property>
    </bean>
    
    <bean id="sessionFactoryMgm"
          class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
        <property name="dataSource" ref="dataSourceMgm" />
        <property name="packagesToScan" value="com.*.*.*" />
        <property name="hibernateProperties">
            <props>
                <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
                <prop key="hibernate.connection.provider_class">org.hibernate.connection.C3P0ConnectionProvider
                </prop>
                <prop key="hibernate.connection.characterEncoding">utf-8</prop>
                <prop key="hibernate.connection.useUnicode">true</prop>
                <prop key="hibernate.show_sql">true</prop>
                <prop key="javax.persistence.validation.mode">none</prop>
            </props>
        </property>
    </bean>
    <bean id="transactionManagerMgm"
          class="org.springframework.orm.hibernate3.HibernateTransactionManager">
        <property name="sessionFactory" ref="sessionFactoryMgm" />
    </bean>
    <bean id="hibernateTemplateMgm" class="org.springframework.orm.hibernate3.HibernateTemplate">
        <property name="sessionFactory" ref="sessionFactoryMgm" />
    </bean>
    <bean id="jdbcTemplateMgm" class="org.springframework.jdbc.core.JdbcTemplate">
        <property name="dataSource" ref="dataSourceMgm" />
    </bean>

同样的需要加上tx驱动:

    <tx:annotation-driven transaction-manager="transactionManagerMgm" />

在service层,只需加上注解 @Transactional 即可。如下:

@Service
@Transactional
public class UserInfoServiceImpl implements UserInfoService {
	@Autowired
	private TblCcmgmUsrInfDao userInfoDao;
	@Autowired
	private TblCcmgmMchntDao mchntInfDao;
	@Autowired
	private TblCcmgmRoleFunctionRelatedDao roleFunctionRelatedDao;
	
	@Override
	public void addUser(UserInfoDto userInfoDto) throws Exception {
		//......
		userInfoDao.save();
		mchntInfDao.save();
		roleFunctionRelatedDao.save();
		//......
	}
}

以上就是简单的事务实现,但是目前以上这些方式,只能实现单库(单数据源)事务实现,实际项目需求中,有很多需要跨机,跨库等需求,这里就需要实现全局事务,全局事务实现下一篇中详见。这一篇与标题无任何关联。

由于近期项目需求,所以一直在网上及项目中研究这块,如果有部分内容与其他资源雷同,请见谅,小老弟也不知道出自何处了。















  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值