好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

Spring使用注解和配置文件配置事务

本文实例为大家分享了Spring使用注解和配置文件配置事务的具体代码,供大家参考,具体内容如下

需求图:

使用注解配置事务:

?

1

2

3

4

5

6

7

8

9

10

11

12

13

package com.atguigu.spring.tx;

 

public interface BookShopDao {

 

     //根据书号获取书的单价

     public int findBookPriceByIsbn(String isbn);

    

     //更新数的库存. 使书号对应的库存 - 1

     public void updateBookStock(String isbn);

    

     //更新用户的账户余额: 使 username 的 balance - price

     public void updateUserAccount(String username, int price);

}

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

package com.atguigu.spring.tx;

 

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.jdbc.core.JdbcTemplate;

import org.springframework.stereotype.Repository;

 

@Repository ( "bookShopDao" )

public class BookShopDaoImpl implements BookShopDao {

 

     @Autowired

     private JdbcTemplate jdbcTemplate;

    

     @Override

     public int findBookPriceByIsbn(String isbn) {

         String sql = "SELECT price FROM book WHERE isbn = ?" ;

         return jdbcTemplate.queryForObject(sql, Integer. class , isbn);

     }

 

     @Override

     public void updateBookStock(String isbn) {

         //检查书的库存是否足够, 若不够, 则抛出异常

         String sql2 = "SELECT stock FROM book_stock WHERE isbn = ?" ;

         int stock = jdbcTemplate.queryForObject(sql2, Integer. class , isbn);

         if (stock == 0 ){

             throw new BookStockException( "库存不足!" );

         }

        

         String sql = "UPDATE book_stock SET stock = stock -1 WHERE isbn = ?" ;

         jdbcTemplate.update(sql, isbn);

     }

 

     @Override

     public void updateUserAccount(String username, int price) {

         //验证余额是否足够, 若不足, 则抛出异常

         String sql2 = "SELECT balance FROM account WHERE username = ?" ;

         int balance = jdbcTemplate.queryForObject(sql2, Integer. class , username);

         if (balance < price){

             throw new UserAccountException( "余额不足!" );

         }

        

         String sql = "UPDATE account SET balance = balance - ? WHERE username = ?" ;

         jdbcTemplate.update(sql, price, username);

     }

 

}

?

1

2

3

4

5

6

7

package com.atguigu.spring.tx;

 

public interface BookShopService {

    

     public void purchase(String username, String isbn);

    

}

事务配置的核心部分:

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

package com.atguigu.spring.tx;

 

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.stereotype.Service;

import org.springframework.transaction.annotation.Isolation;

import org.springframework.transaction.annotation.Propagation;

import org.springframework.transaction.annotation.Transactional;

 

@Service ( "bookShopService" )

public class BookShopServiceImpl implements BookShopService {

 

     @Autowired

     private BookShopDao bookShopDao;

    

     //添加事务注解

     //1.使用 propagation 指定事务的传播行为, 即当前的事务方法被另外一个事务方法调用时

     //REQUIRED:为默认取值, 被调用的事务一个执行失败整个大事务就回滚

     //REQUIRES_NEW:调用的事务如果执行成功就保存结果不会被回滚,其他事务执行失败不会影响到它

     //2.使用 isolation 指定事务的隔离级别, 最常用的取值为 READ_COMMITTED

     //3.默认情况下 Spring 的声明式事务对所有的运行时异常进行回滚. 也可以通过对应的

     //属性进行设置. 通常情况下取默认值即可. 

     //4.使用 readOnly 指定事务是否为只读. 表示这个事务只读取数据但不更新数据, 

     //这样可以帮助数据库引擎优化事务. 若方法只读取数据库值, 应设置 readOnly=true

     //5.使用 timeout 指定事务最多可以占用的时间,若超过时间则强制回滚 

//    @Transactional(propagation=Propagation.REQUIRES_NEW,

//            isolation=Isolation.READ_COMMITTED,

//            noRollbackFor={UserAccountException.class})

     @Transactional (propagation=Propagation.REQUIRES_NEW,

             isolation=Isolation.READ_COMMITTED,

             readOnly= false ,

             timeout= 3 )

     @Override

     public void purchase(String username, String isbn) {

        

         try {

             Thread.sleep( 5000 );

         } catch (InterruptedException e) {}

        

         //1. 获取书的单价

         int price = bookShopDao.findBookPriceByIsbn(isbn);

        

         //2. 更新数的库存

         bookShopDao.updateBookStock(isbn);

        

         //3. 更新用户余额

         bookShopDao.updateUserAccount(username, price);

     }

 

}

?

1

2

3

4

5

6

7

8

9

package com.atguigu.spring.tx;

 

import java.util.List;

 

public interface Cashier {

 

     public void checkout(String username, List<String> isbns);

    

}

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

package com.atguigu.spring.tx;

 

import java.util.List;

 

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.stereotype.Service;

import org.springframework.transaction.annotation.Transactional;

 

@Service ( "cashier" )

public class CashierImpl implements Cashier {

 

     @Autowired

     private BookShopService bookShopService;

    

     @Transactional

     @Override

     public void checkout(String username, List<String> isbns) {

         for (String isbn: isbns){

             bookShopService.purchase(username, isbn);

         }

     }

 

}

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

package com.atguigu.spring.tx;

 

import static org.junit.Assert.*;

 

import java.util.Arrays;

 

import org.junit.Test;

import org.springframework.context.ApplicationContext;

import org.springframework.context.support.ClassPathXmlApplicationContext;

 

public class SpringTransactionTest {

 

     private ApplicationContext ctx = null ;

     private BookShopDao bookShopDao = null ;

     private BookShopService bookShopService = null ;

     private Cashier cashier = null ;

    

     {

         ctx = new ClassPathXmlApplicationContext( "applicationContext.xml" );

         bookShopDao = ctx.getBean(BookShopDao. class );

         bookShopService = ctx.getBean(BookShopService. class );

         cashier = ctx.getBean(Cashier. class );

     }

    

     @Test

     public void testTransactionlPropagation(){

         cashier.checkout( "AA" , Arrays.asList( "1001" , "1002" ));

     }

    

     @Test

     public void testBookShopService(){

         bookShopService.purchase( "AA" , "1001" );

     }

    

     @Test

     public void testBookShopDaoUpdateUserAccount(){

         bookShopDao.updateUserAccount( "AA" , 200 );

     }

    

     @Test

     public void testBookShopDaoUpdateBookStock(){

         bookShopDao.updateBookStock( "1001" );

     }

    

     @Test

     public void testBookShopDaoFindPriceByIsbn() {

         System.out.println(bookShopDao.findBookPriceByIsbn( "1001" ));

     }

 

}

BookStockException、UserAccountException为自定义异常类!

配置文件:

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

<? xml version = "1.0" encoding = "UTF-8" ?>

< beans xmlns = "http://HdhCmsTestspringframework.org/schema/beans"

     xmlns:xsi = "http://HdhCmsTestw3.org/2001/XMLSchema-instance"

     xmlns:context = "http://HdhCmsTestspringframework.org/schema/context"

     xmlns:tx = "http://HdhCmsTestspringframework.org/schema/tx"

     xsi:schemaLocation="http://HdhCmsTestspringframework.org/schema/beans http://HdhCmsTestspringframework.org/schema/beans/spring-beans.xsd

         http://HdhCmsTestspringframework.org/schema/tx http://HdhCmsTestspringframework.org/schema/tx/spring-tx-4.0.xsd

         http://HdhCmsTestspringframework.org/schema/context http://HdhCmsTestspringframework.org/schema/context/spring-context-4.0.xsd">

    

     < context:component-scan base-package = "com.atguigu.spring" ></ context:component-scan >

    

     <!-- 导入资源文件 -->

     < context:property-placeholder location = "classpath:db.properties" />

    

     <!-- 配置 C3P0 数据源 -->

     < bean id = "dataSource"

         class = "com.mchange.v2.c3p0.ComboPooledDataSource" >

         < property name = "user" value = "${jdbc.user}" ></ property >

         < property name = "password" value = "${jdbc.password}" ></ property >

         < property name = "jdbcUrl" value = "${jdbc.jdbcUrl}" ></ property >

         < property name = "driverClass" value = "${jdbc.driverClass}" ></ property >

 

         < property name = "initialPoolSize" value = "${jdbc.initPoolSize}" ></ property >

         < property name = "maxPoolSize" value = "${jdbc.maxPoolSize}" ></ property >

     </ bean >

    

     <!-- 配置 Spirng 的 JdbcTemplate -->

     < bean id = "jdbcTemplate"

         class = "org.springframework.jdbc.core.JdbcTemplate" >

         < property name = "dataSource" ref = "dataSource" ></ property >

     </ bean >

    

     <!-- 配置 NamedParameterJdbcTemplate, 该对象可以使用具名参数, 其没有无参数的构造器, 所以必须为其构造器指定参数 -->

     < bean id = "namedParameterJdbcTemplate"

         class = "org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate" >

         < constructor-arg ref = "dataSource" ></ constructor-arg >    

     </ bean >

    

     <!-- 配置事务管理器 -->

     < bean id = "transactionManager"

         class = "org.springframework.jdbc.datasource.DataSourceTransactionManager" >

         < property name = "dataSource" ref = "dataSource" ></ property >

     </ bean >

    

     <!-- 启用事务注解 -->

     < tx:annotation-driven transaction-manager = "transactionManager" />

    

</ beans >

配置文件(使用配置文件配置事务,以上类的注解需要全部删除):

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

<? xml version = "1.0" encoding = "UTF-8" ?>

< beans xmlns = "http://HdhCmsTestspringframework.org/schema/beans"

     xmlns:xsi = "http://HdhCmsTestw3.org/2001/XMLSchema-instance"

     xmlns:context = "http://HdhCmsTestspringframework.org/schema/context"

     xmlns:tx = "http://HdhCmsTestspringframework.org/schema/tx"

     xmlns:aop = "http://HdhCmsTestspringframework.org/schema/aop"

     xsi:schemaLocation="http://HdhCmsTestspringframework.org/schema/aop http://HdhCmsTestspringframework.org/schema/aop/spring-aop-4.0.xsd

         http://HdhCmsTestspringframework.org/schema/beans http://HdhCmsTestspringframework.org/schema/beans/spring-beans.xsd

         http://HdhCmsTestspringframework.org/schema/tx http://HdhCmsTestspringframework.org/schema/tx/spring-tx-4.0.xsd

         http://HdhCmsTestspringframework.org/schema/context http://HdhCmsTestspringframework.org/schema/context/spring-context-4.0.xsd">

    

     < context:component-scan base-package = "com.atguigu.spring" ></ context:component-scan >

    

     <!-- 导入资源文件 -->

     < context:property-placeholder location = "classpath:db.properties" />

    

     <!-- 配置 C3P0 数据源 -->

     < bean id = "dataSource"

         class = "com.mchange.v2.c3p0.ComboPooledDataSource" >

         < property name = "user" value = "${jdbc.user}" ></ property >

         < property name = "password" value = "${jdbc.password}" ></ property >

         < property name = "jdbcUrl" value = "${jdbc.jdbcUrl}" ></ property >

         < property name = "driverClass" value = "${jdbc.driverClass}" ></ property >

 

         < property name = "initialPoolSize" value = "${jdbc.initPoolSize}" ></ property >

         < property name = "maxPoolSize" value = "${jdbc.maxPoolSize}" ></ property >

     </ bean >

    

     <!-- 配置 Spirng 的 JdbcTemplate -->

     < bean id = "jdbcTemplate"

         class = "org.springframework.jdbc.core.JdbcTemplate" >

         < property name = "dataSource" ref = "dataSource" ></ property >

     </ bean >

    

     <!-- 配置 bean -->

     < bean id = "bookShopDao" class = "com.atguigu.spring.tx.xml.BookShopDaoImpl" >

         < property name = "jdbcTemplate" ref = "jdbcTemplate" ></ property >

     </ bean >

    

     < bean id = "bookShopService" class = "com.atguigu.spring.tx.xml.service.impl.BookShopServiceImpl" >

         < property name = "bookShopDao" ref = "bookShopDao" ></ property >

     </ bean >

    

     < bean id = "cashier" class = "com.atguigu.spring.tx.xml.service.impl.CashierImpl" >

         < property name = "bookShopService" ref = "bookShopService" ></ property >

     </ bean >

    

     <!-- 1. 配置事务管理器 -->

     < bean id = "transactionManager" class = "org.springframework.jdbc.datasource.DataSourceTransactionManager" >

         < property name = "dataSource" ref = "dataSource" ></ property >

     </ bean >

    

     <!-- 2. 配置事务属性 -->

     < tx:advice id = "txAdvice" transaction-manager = "transactionManager" >

         < tx:attributes >

             <!-- 根据方法名指定事务的属性 -->

             < tx:method name = "purchase" propagation = "REQUIRES_NEW" />

             < tx:method name = "get*" read-only = "true" />

             < tx:method name = "find*" read-only = "true" />

             < tx:method name = "*" />

         </ tx:attributes >

     </ tx:advice >

    

     <!-- 3. 配置事务切入点, 以及把事务切入点和事务属性关联起来 -->

     < aop:config >

         < aop:pointcut expression = "execution(* com.atguigu.spring.tx.xml.service.*.*(..))"

             id = "txPointCut" />

         < aop:advisor advice-ref = "txAdvice" pointcut-ref = "txPointCut" />    

     </ aop:config >

    

</ beans >

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。

原文链接:https://blog.csdn.net/x297910962/article/details/79595777

查看更多关于Spring使用注解和配置文件配置事务的详细内容...

  阅读:17次