主配置文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd">
<context:component-scan base-package="com"/>
<bean id="runner" class="org.apache.commons.dbutils.QueryRunner" scope="prototype">
</bean>
<!-- 配置数据源-->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<!-- 连接数据库的必备信息-->
<property name="driverClass" value="com.mysql.cj.jdbc.Driver"></property>
<property name="jdbcUrl" value="jdbc:mysql:///db1"></property>
<property name="user" value="root"></property>
<property name="password" value="zheng"></property>
</bean>
<!-- 配置Connection的工具类-->
<bean id="connectionUtils" class="com.utils.ConnectionUtils">
<property name="dataSource" ref="dataSource"></property>
</bean>
<!-- 事务管理器-->
<bean id="transManager" class="com.utils.TransactionManager">
<property name="connectionUtils" ref="connectionUtils"></property>
</bean>
</beans>
单连接类
public class ConnectionUtils {
private ThreadLocal<Connection> t1 = new ThreadLocal<Connection>();
private DataSource dataSource;
public DataSource getDataSource() {
return dataSource;
}
public void setDataSource(DataSource dataSource) {
this.dataSource = dataSource;
}
public Connection getConnection()
{
Connection connection = t1.get();
if (connection == null)
{
try {
connection = dataSource.getConnection();
} catch (SQLException e) {
e.printStackTrace();
}
t1.set(connection);
}
return connection;
}
public void remove()
{
t1.remove();
}
}
管理连接的事务类
public class TransactionManager {
private ConnectionUtils connectionUtils;
public ConnectionUtils getConnectionUtils() {
return connectionUtils;
}
public void setConnectionUtils(ConnectionUtils connectionUtils) {
this.connectionUtils = connectionUtils;
}
public void beginTransaction(){
try {
connectionUtils.getConnection().setAutoCommit(false);
} catch (SQLException e) {
e.printStackTrace();
}
}
public void CommitTransaction(){
try {
connectionUtils.getConnection().commit();
} catch (SQLException e) {
e.printStackTrace();
}
}
public void RollTransaction(){
try {
connectionUtils.getConnection().rollback();
} catch (SQLException e) {
e.printStackTrace();
}
}
public void release(){
try {
connectionUtils.getConnection().close();
connectionUtils.remove();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
在业务层中加入事务控制
@Service("accountService")
public class IAccountService implements IAccountAervice {
@Autowired
private IAccountDao dao;
@Autowired
private TransactionManager transactionManager;
public TransactionManager getTransactionManager() {
return transactionManager;
}
public void setTransactionManager(TransactionManager transactionManager) {
this.transactionManager = transactionManager;
}
public IAccountDao getDao() {
return dao;
}
public void setDao(IAccountDao dao) {
this.dao = dao;
}
public List<Account> findAllAccount() {
try{
transactionManager.beginTransaction();
List<Account> list = dao.findAllAccount();
transactionManager.CommitTransaction();
return list;
}catch (Exception e){
transactionManager.RollTransaction();
throw new RuntimeException();
}finally {
transactionManager.release();
}
}
public Account findById(Integer i) {
try{
transactionManager.beginTransaction();
Account list = dao.findById(i);
transactionManager.CommitTransaction();
return list;
}catch (Exception e){
transactionManager.RollTransaction();
throw new RuntimeException();
}finally {
transactionManager.release();
}
}
public void saveAccount(Account account) {
try{
transactionManager.beginTransaction();
dao.saveAccount(account);
transactionManager.CommitTransaction();
}catch (Exception e){
transactionManager.RollTransaction();
}finally {
transactionManager.release();
}
}
public void updateAccount(Account account) {
try{
transactionManager.beginTransaction();
dao.updateAccount(account);
transactionManager.CommitTransaction();
}catch (Exception e){
transactionManager.RollTransaction();
}finally {
transactionManager.release();
}
}
public void deleteAccount(Integer i) {
try{
transactionManager.beginTransaction();
dao.deleteAccount(i);
transactionManager.CommitTransaction();
}catch (Exception e){
transactionManager.RollTransaction();
}finally {
transactionManager.release();
}
}
public void transfer(String sourceName, String targetName, Float money) throws Exception {
try{
transactionManager.beginTransaction();
Account source = dao.findByName(sourceName);
Account target = dao.findByName(targetName);
source.setMoney(source.getMoney() - money);
target.setMoney(target.getMoney() +money);
dao.updateAccount(source);
int i = 2/0;
dao.updateAccount(target);
transactionManager.CommitTransaction();
}catch (Exception e){
transactionManager.RollTransaction();
throw new RuntimeException("事务出错");
}finally {
transactionManager.release();
}
}
}
改变持久层,将单线程中的连接注入QueryRunner方法中
@Repository("accuntDaoImp")
public class IAccuntDaoImp implements IAccountDao {
@Autowired
private QueryRunner runner;
@Autowired
private ConnectionUtils connectionUtils;
public QueryRunner getRunner() {
return runner;
}
public void setRunner(QueryRunner runner) {
this.runner = runner;
}
public List<Account> findAllAccount() {
try {
return runner.query(connectionUtils.getConnection(),"select * from account2", new BeanListHandler<Account>(Account.class));
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
public Account findById(Integer i) {
try {
return runner.query(connectionUtils.getConnection(),"select * from account2 where id = ?", new BeanHandler<Account>(Account.class),i);
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
public void saveAccount(Account account) {
try {
runner.update(connectionUtils.getConnection(),"insert into account2(username,money) values(?,?)", account.getUsername(), account.getMoney());
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
public void updateAccount(Account account) {
try {
runner.update(connectionUtils.getConnection(),"update account2 set username=?, money =? where id = ?",
account.getUsername(), account.getMoney(), account.getId());
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
public void deleteAccount(Integer i) {
try {
runner.update(connectionUtils.getConnection(),"delete from account2 where id = ?", i);
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
public Account findByName(String sourceName) throws Exception {
try {
List<Account> lists = runner.query(connectionUtils.getConnection(),"select * from account2 where username = ?", new BeanListHandler<Account>(Account.class),sourceName);
if (lists == null || lists.size() == 0)
{
return null;
}
if (lists.size() > 1)
{
throw new Exception("数据不唯一");
}
return lists.get(0);
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
}
测试类
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:bean.xml")
public class AccountTest {
@Autowired
IAccountService accountService = null;
@Test
public void tesTransaction()
{
////执行方法
try {
accountService.transfer("hao","chen",5.0f);
} catch (Exception e) {
e.printStackTrace();
}
testfindAll();
}
}
网友评论