Spring & Transaction

  • 事务作用:在数据层保证一系列的数据库操作同成功同失败

  • Spring事务作用:在数据层或者业务层保障一系列的数据库操作同成功同失败

  • 接口:PlatfromTransactionManager

  • 实现类:DataSourceTransactionManager (底层是jdbc,和spring一样)

  • Spring 事务角色

    • 事务管理员:在业务层开启的事务,其它的事务都加入这个事务中,统一完成事务,做到了同成功同失败

    • 事务协调员:就是被加入的事务,指的是数据层的方法,也可以是业务层的方法。

config

package com.yang.config;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.context.annotation.PropertySource;
import org.springframework.transaction.annotation.EnableTransactionManagement;

@Configuration
@ComponentScan("com.yang")
@PropertySource("jdbc.properties")
@Import({JdbcConfig.class,MybatisConfig.class})
@EnableTransactionManagement//开启事务
public class SpringConfig {
}

jdbcConfig

package com.yang.config;

import com.alibaba.druid.pool.DruidDataSource;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.PlatformTransactionManager;

import javax.sql.DataSource;

public class JdbcConfig {
   @Value("${jdbc.driver}")
   private String driver;
   @Value("${jdbc.url}")
   private String url;
   @Value("${jdbc.username}")
   private String username;
   @Value("${jdbc.password}")
   private String password;

   @Bean
   public DataSource dataSource(){
       DruidDataSource data = new DruidDataSource();
       data.setPassword(password);
       data.setUsername(username);
       data.setUrl(url);
       data.setDriverClassName(driver);
       return data;
  }
   @Bean
   public PlatformTransactionManager transactionManager(DataSource data){
       DataSourceTransactionManager dtm = new DataSourceTransactionManager();
       dtm.setDataSource(data);
       return dtm;
  }
}

service

package com.yang.service;

import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

@Transactional(propagation = Propagation.REQUIRES_NEW)//开启独立的新事务
public interface LogService {
   void log(String out,String in,double money);
}

 

package com.yang.service;

import org.springframework.transaction.annotation.Transactional;

import java.io.IOException;

//可以加方法上;也可以加接口上,表示所有的方法都开始起事务
@Transactional
public interface AccountService {
   //rollbackFor指定异常回滚,有的异常是不会回滚的,例IOException
   //rollbackFor = {IOException.class}

   void accountService(String outAccount,String inAccount ,double money) throws IOException;
}

AccountServiceImpl.java

package com.yang.service.Impl;

import com.yang.dao.AccountDao;
import com.yang.service.AccountService;
import com.yang.service.LogService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.IOException;

@Service
public class AccountServiceImpl implements AccountService {

   @Autowired
   private AccountDao accountDao;
   @Autowired
   private LogService logService;

   @Override
   public void accountService(String out, String in, double money) throws IOException {

       try {
           accountDao.outAccount(out, money);
//           int i = 1 / 0;
//           if (true) {throw new IOException();}
           accountDao.inAccount(in, money);
      } finally {
           logService.log(out,in,money);
           System.out.println("我爱你");
      }
  }
}

test

package com.yang;

import com.yang.config.SpringConfig;
import com.yang.service.AccountService;
import org.junit.Test;
import org.junit.runner.RunWith;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import java.io.IOException;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = SpringConfig.class)
public class TransactionTest {
   @Autowired
   private AccountService accountService;
   @Test
   public void account() throws IOException {
       accountService.accountService("Tom","Jack",100);
  }
}