• Spring Data Jpa 简单使用事务


    对于两张表,需要顺序操作,必须全部表均操作成功才可,否则两张表不操作。

    例如,现在有device,collectionpoint两张表,向两张表顺序执行insert操作
    SQL如下
    1. INSERT INTO device (dev_id, tenant_id, user_id)
    2. VALUES
    3. ('bangjile', 909, 909);
    4. INSERT INTO collectionpoint (
    5. device_id,
    6. tenant_id,
    7. point_name
    8. )
    9. VALUES
    10. (808,808,'ceshihahah');
    这种方式下,必须两条语句均成功才可,否则均不成功

    使用JPA进行操作
    现有device的repository
    1. @Repository
    2. public interface DeviceEntityRepository extends JpaRepository<DeviceEntity,Integer> {}
    collectionpoint的repository
    1. @Repository
    2. public interface CollectionPointRepository extends JpaRepository<CollectionpointEntity,Integer> {}

    新建一个测试repository,用来测试事务操作
    1. @Repository
    2. public class TestRepository {
    3. @Autowired
    4. DeviceEntityRepository deviceEntityRepository;
    5. @Autowired
    6. CollectionPointRepository repository;
    7. public void testMethod(){
    8. DeviceEntity deviceEntity=new DeviceEntity();
    9. deviceEntity.setDevId("gogogo12");
    10. deviceEntity.setTenantId(88);
    11. deviceEntity.setUserId(88);
    12. deviceEntityRepository.save(deviceEntity);
    13. CollectionpointEntity collectionpointEntity=new CollectionpointEntity();
    14. collectionpointEntity.setDeviceId(8);
    15. collectionpointEntity.setTenantId(88);
    16. collectionpointEntity.setPointName("chongtu11");
    17. repository.save(collectionpointEntity);
    18. }
    19. }

    执行该测试方法,两条数据均写入成功。
    由于测试方法中的实体类赋值了非空键和唯一键。下面来测试device写入成功,collectionpoint写入冲突的情况
    1. public void testMethod(){
    2. DeviceEntity deviceEntity=new DeviceEntity();
    3. deviceEntity.setDevId("gogogo122");
    4. ...
    5. CollectionpointEntity collectionpointEntity=new CollectionpointEntity();
    6. collectionpointEntity.setDeviceId(8);
    7. collectionpointEntity.setTenantId(88);
    8. collectionpointEntity.setPointName("chongtu11");
    9. repository.save(collectionpointEntity);
    10. }
    执行方法,调试窗口显示collectionpoint冲突,但查看数据库显示device表中新增了gogogo122的数据,说明整个testMethod方法不具有事务性

    事务实现:
    只需要在testMethod上方添加一句注解即可
    1. @Transactional(readOnly = false, rollbackFor = Throwable.class)
    2. public void testMethod(){
    3. ...
    4. }
    现在再次修改device实体数据,使写入非冲突,collectionpoint实体保持冲突。
    执行方法,调试窗口显示collectionpoint冲突,但数据库中device表中为增加新数据。
    调试信息如下,显示了jpa的整个过程
    1. 06-02 18:03:51.386 DEBUG 11624 --- [nio-8089-exec-1] org.hibernate.SQL : insert into public.device (dev_desc, dev_id, dev_manufacture, dev_note, dev_position1, dev_position2, dev_sn, dev_type, emp_id, tenant_id, user_id, id) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
    2. Hibernate: insert into public.device (dev_desc, dev_id, dev_manufacture, dev_note, dev_position1, dev_position2, dev_sn, dev_type, emp_id, tenant_id, user_id, id) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
    3. 2017-06-02 18:03:51.392 DEBUG 11624 --- [nio-8089-exec-1] org.hibernate.SQL : insert into public.collectionpoint (device_id, point_alarm_contacts, point_alarm_flag, point_desc, point_downlimit, point_downlimit2, point_name, point_scale, point_type, point_unit, point_uplimit, point_uplimit2, tenant_id, id) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
    4. Hibernate: insert into public.collectionpoint (device_id, point_alarm_contacts, point_alarm_flag, point_desc, point_downlimit, point_downlimit2, point_name, point_scale, point_type, point_unit, point_uplimit, point_uplimit2, tenant_id, id) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
    5. 2017-06-02 18:03:51.404 ERROR 11624 --- [nio-8089-exec-1] druid.sql.Statement : {conn-10005, pstmt-20004} execute error. insert into public.collectionpoint (device_id, point_alarm_contacts, point_alarm_flag, point_desc, point_downlimit, point_downlimit2, point_name, point_scale, point_type, point_unit, point_uplimit, point_uplimit2, tenant_id, id) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
    6. org.postgresql.util.PSQLException: ERROR: duplicate key value violates unique constraint "collectionpoint_point_name_device_id_tenant_id_key"
    7. 详细:Key (point_name, device_id, tenant_id)=(chongtu11, 8, 88) already exists.
    8. ................................此处为异常信息...................
    9. 2017-06-02 18:03:51.409 DEBUG 11624 --- [nio-8089-exec-1] o.h.engine.jdbc.spi.SqlExceptionHelper : could not execute statement [n/a]
    10. ................................此处为异常信息...................
    11. 2017-06-02 18:03:51.410 WARN 11624 --- [nio-8089-exec-1] o.h.engine.jdbc.spi.SqlExceptionHelper : SQL Error: 0, SQLState: 23505
    12. 2017-06-02 18:03:51.410 ERROR 11624 --- [nio-8089-exec-1] o.h.engine.jdbc.spi.SqlExceptionHelper : ERROR: duplicate key value violates unique constraint "collectionpoint_point_name_device_id_tenant_id_key"
    13. 详细:Key (point_name, device_id, tenant_id)=(chongtu11, 8, 88) already exists.
    14. 2017-06-02 18:03:51.412 INFO 11624 --- [nio-8089-exec-1] o.h.e.j.b.internal.AbstractBatchImpl : HHH000010: On release of batch it still contained JDBC statements
    15. 2017-06-02 18:03:51.413 DEBUG 11624 --- [nio-8089-exec-1] o.h.jpa.spi.AbstractEntityManagerImpl : Mark transaction for rollback
    16. 2017-06-02 18:03:51.415 DEBUG 11624 --- [nio-8089-exec-1] cResourceLocalTransactionCoordinatorImpl : JDBC transaction marked for rollback-only (exception provided for stack trace)
    17. ................................此处为异常信息...................
    18. 2017-06-02 18:03:51.421 DEBUG 11624 --- [nio-8089-exec-1] o.h.jpa.spi.AbstractEntityManagerImpl : Mark transaction for rollback
    19. 2017-06-02 18:03:51.421 DEBUG 11624 --- [nio-8089-exec-1] o.h.e.t.internal.TransactionImpl : rollback() called on an inactive transaction
    20. 2017-06-02 18:03:51.422 DEBUG 11624 --- [nio-8089-exec-1] .m.m.a.ExceptionHandlerExceptionResolver : Resolving exception from handler [public void com.yginsight.adminservice.app.api.TestController.test()]: org.springframework.dao.DataIntegrityViolationException: could not execute statement; SQL [n/a]; constraint [collectionpoint_point_name_device_id_tenant_id_key]; nested exception is org.hibernate.exception.ConstraintViolationException: could not execute statement
    21. 2017-06-02 18:03:51.424 DEBUG 11624 --- [nio-8089-exec-1] .w.s.m.a.ResponseStatusExceptionResolver : Resolving exception from handler [public void com.yginsight.adminservice.app.api.TestController.test()]: org.springframework.dao.DataIntegrityViolationException: could not execute statement; SQL [n/a]; constraint [collectionpoint_point_name_device_id_tenant_id_key]; nested exception is org.hibernate.exception.ConstraintViolationException: could not execute statement
    22. 2017-06-02 18:03:51.424 DEBUG 11624 --- [nio-8089-exec-1] .w.s.m.s.DefaultHandlerExceptionResolver : Resolving exception from handler [public void com.yginsight.adminservice.app.api.TestController.test()]: org.springframework.dao.DataIntegrityViolationException: could not execute statement; SQL [n/a]; constraint [collectionpoint_point_name_device_id_tenant_id_key]; nested exception is org.hibernate.exception.ConstraintViolationException: could not execute statement
    23. 2017-06-02 18:03:51.424 DEBUG 11624 --- [nio-8089-exec-1] o.h.e.jdbc.internal.JdbcCoordinatorImpl : HHH000420: Closing un-released batch
    24. 2017-06-02 18:03:51.428 DEBUG 11624 --- [nio-8089-exec-1] o.s.web.servlet.DispatcherServlet : Could not complete request

  • 相关阅读:
    基于udp简单聊天的系统
    网络编程_tcp与dup协议简单应用
    logging_modules
    linux内核配置与编译
    linux内核简介
    对于国嵌上学期《一跃进入C大门》Mini2440的代码修正
    通过按键玩中断
    MMU功能解析、深入剖析、配置与使用
    C与汇编混合编程
    一跃进入C大门
  • 原文地址:https://www.cnblogs.com/tilv37/p/6934636.html
Copyright © 2020-2023  润新知