您的位置:首页 > 编程语言 > Java开发

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

2017-05-11 16:20 579 查看

引言:

事务(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();
//......
}
}


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

由于近期项目需求,所以一直在网上及项目中研究这块,如果有部分内容与其他资源雷同,请见谅,小老弟也不知道出自何处了。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  spring 事务 数据库