1. 程式人生 > >spring @Transactional註解用於事務回滾案例

spring @Transactional註解用於事務回滾案例

這裡基於小編的這篇博文的spring配置和實體類,service類為基礎,解釋@Transactional註解:

注意這裡@Transcational註解起作用的前提是要使用spring的宣告式事務:

  <!-- 配置宣告式事務 -->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"></property>
    </bean>

 上面的配置在之前的博文中有配置過。

package redisCache.service.impl;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import redisCache.entity.User;
import redisCache.mapper.UserMapper;
import redisCache.service.UserService;

/**
 * Created by jiangfeixiang on 2018/4/27
 */
@Service("userService")
@Transactional
public class UserServiceImpl implements UserService {
    //注入userMapper
    @Autowired
    private UserMapper userMapper;

    /**
     * 新增使用者
     */
    @Override
    public void insertUser(User user){
        userMapper.insertUser(user);
        System.out.println("-------------");
        String string  = null;
   	    if(string.equals("")) {
   	        int i = 0;
   	    }
    }    
    
}

上面的程式碼我們在類上加上了transactional註解,方法中有一個插入的資料的方法,然後是故意做一個異常,讓事務回滾。

測試類:

package redisCache;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import redisCache.entity.User;
import redisCache.service.UserService;
public class TestTransactional {
	public static void main(String[] args) {
		ApplicationContext applicationContext=new ClassPathXmlApplicationContext("applicationContext.xml");
		UserService userService=(UserService) applicationContext.getBean("userService");
    	User u=new User();
    	u.setId(1);
    	u.setUsername("xiaoming");
    	userService.insertUser(u);
    	
	}

}

然後執行測試類,最好debug執行,當走完service方法的插入到資料庫操作時,你到資料庫看,會發現資料庫並沒有插入資料。繼續往下走就會丟擲異常,資料庫始終沒有資料,儲存也就沒有成功。如果把service註解去掉,就會看到及時報異常,資料庫也儲存成功了。

在實際工作中我們更多的是遇到有多個關聯的表都需要儲存,很明顯,為了保證事務的原子性,這些儲存要麼全部成功,要麼全部失敗。此時我就想到與要報這些儲存都放在一個service方法中,如下:

 public void insertUser(User user){
        userMapper.insertUser(user);
        User user2=new User();
        user2.setId(2);
        user2.setUsername("xiaohua");
        userMapper.insertUser(user2);
        User user3=new User();
        user3.setId(2);
        user3.setUsername("xiaohua");
        userMapper.insertUser(user3);
        System.out.println("-------------");
        String string  = null;
   	    if(string.equals("")) {
   	        int i = 0;
   	    }
    }

上面的user,user2,user3儲存就相當於有多個事務,這些事務在遇到下面的異常時,就會全部回滾,從而保證了事務的原子性。