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

来源:互联网 发布:mysql unique 修改 编辑:程序博客网 时间:2024/05/21 15:49

引言:

事务(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@Transactionalpublic class UserInfoServiceImpl implements UserInfoService {@Autowiredprivate TblCcmgmUsrInfDao userInfoDao;@Autowiredprivate TblCcmgmMchntDao mchntInfDao;@Autowiredprivate TblCcmgmRoleFunctionRelatedDao roleFunctionRelatedDao;@Overridepublic void addUser(UserInfoDto userInfoDto) throws Exception {//......userInfoDao.save();mchntInfDao.save();roleFunctionRelatedDao.save();//......}}

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

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















0 0
原创粉丝点击