简体   繁体   English

在Spring数据JPA的同一笔交易中看不到修改,为什么在同一笔交易中修改后却为空?

[英]the modifying can not be visible in the same transaction in spring data jpa,why i got null after modifying in the same transaction?

show code first,here is my code,as below: 首先显示代码,这是我的代码,如下所示:

   public void saveTestTx() {
        Lock lock = new Lock();
        lock.setName("ABCDEFG");
        lock.setDeviceId("22dfgdfgdftrtg");
        lock.setCreateTime((new Date()));
        Lock lock1 = lockDao.saveAndFlush(lock);
        System.out.println("lock1 = " + lock1);
        Lock lock2 = lockDao.findByDeviceId(lock.getDeviceId());
        System.out.println("lock2 = " + lock2);  // got null here
    }

enter image description here (here is the screenshot) 此处输入图片说明 (这是屏幕截图)

i'm sure that the method 'saveTestTx()' is a completely transaction , because if i called print(22/0) ,it can be rolled back. 我确定方法'saveTestTx()'是一个完全事务,因为如果我调用print(22/0),它可以回滚。 i mean that the codes from line 192 to line 199 are in the a same transaction . 我的意思是从192行到199行的代码在同一笔交易中。 from my java development experience, i think the lock2 is the result of lock1, i know that before printing the lock2,the transaction have not commited yet,but they are in a same transaction,the modifying in the same transaction would be visible ,so before comitting transaction,it could be selected from after called "saveAndFlush()" method, and the insert statement is printed at console,but in fact, why lock2 is printed null? 从我的Java开发经验来看,我认为lock2是lock1的结果,我知道在打印lock2之前,事务尚未提交,但是它们在同一事务中,在同一事务中进行修改将是可见的,因此在提交事务之前,可以从调用“ saveAndFlush()”方法之后进行选择,然后在控制台上打印insert语句,但实际上为什么将lock2打印为null?

my transaction configration is as below: 我的交易配置如下:

@Configuration
public class TxConfig {
    @Bean("txSource")
    public TransactionAttributeSource transactionAttributeSource() {
        NameMatchTransactionAttributeSource source = new NameMatchTransactionAttributeSource();
        RuleBasedTransactionAttribute readOnlyTx = new RuleBasedTransactionAttribute();
        readOnlyTx.setReadOnly(true);
        readOnlyTx.setPropagationBehavior(TransactionDefinition.PROPAGATION_NOT_SUPPORTED);
        RuleBasedTransactionAttribute requiredTx = new RuleBasedTransactionAttribute(TransactionDefinition.PROPAGATION_REQUIRED,
                Collections.singletonList(new RollbackRuleAttribute(Exception.class)));
        int isolationLevel = requiredTx.getIsolationLevel();
        // requiredTx.setTimeout(90);
        Map<String, TransactionAttribute> txMap = new HashMap<>();
        txMap.put("init*", requiredTx);
        txMap.put("add*", requiredTx);
        txMap.put("save*", requiredTx);
        txMap.put("insert*", requiredTx);
        txMap.put("create*", requiredTx);
        txMap.put("persist*", requiredTx);
        txMap.put("update*", requiredTx);
        txMap.put("modify*", requiredTx);
        txMap.put("merge*", requiredTx);
        txMap.put("bind*", requiredTx);
        txMap.put("delete*", requiredTx);
        txMap.put("del*", requiredTx);
        txMap.put("drop*", requiredTx);
        txMap.put("remove*", requiredTx);
        txMap.put("reset*", requiredTx);
        txMap.put("cancel*", requiredTx);
        txMap.put("login*", requiredTx);
        txMap.put("*", readOnlyTx);
        source.setNameMap(txMap);
        return source;
    }


    @Bean
    public AspectJExpressionPointcutAdvisor pointcutAdvisor(TransactionInterceptor txInterceptor) {
        AspectJExpressionPointcutAdvisor pointcutAdvisor = new AspectJExpressionPointcutAdvisor();
        pointcutAdvisor.setAdvice(txInterceptor);
//    pointcutAdvisor.setExpression("execution (* com.hl..service..*.*(..))");
        pointcutAdvisor.setExpression("execution (* com..service..*.*(..)) || execution (* com..dao..*.*(..))");
        return pointcutAdvisor;
    }

    @Bean("txInterceptor")
    TransactionInterceptor getTransactionInterceptor(PlatformTransactionManager tx) {
        return new TransactionInterceptor(tx, transactionAttributeSource());
    }

}

my entity code is as below: 我的实体代码如下:

@Data
@ToString(callSuper = true)
@Entity
@Table(name = "police_lock")
@SQLDelete(sql = "update lock set is_deleted = 1 where id = ?")
@Where(clause = "is_deleted = 0")
@DynamicInsert
@DynamicUpdate
public class Lock extends LongBaseEntity {
    public static interface AddGroup {};
    public static interface UpdateGroup {};

    private static final long serialVersionUID = 1L;

    public Lock() {
        super();
    }

    public Lock(Long id) {
        this.id = id;
    }
    public Lock(boolean isInit) {
        super(isInit);
    }
    @NotBlank(groups = {AddGroup.class,UpdateGroup.class})
    private String deviceId;

    @NotBlank(groups = {AddGroup.class,UpdateGroup.class})
    private String name;
}

my table is as below: 我的表如下:

SET FOREIGN_KEY_CHECKS=0;

-- ----------------------------
-- Table structure for police_lock
-- ----------------------------
DROP TABLE IF EXISTS `police_lock`;
CREATE TABLE `police_lock` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `device_id` varchar(36) NOT NULL COMMENT 'device_id',
  `name` varchar(40) NOT NULL COMMENT 'name',
  `create_time` datetime NOT NULL COMMENT 'create_time',
 `is_deleted` bit(1) DEFAULT b'0' COMMENT 'is_deleted',  
  PRIMARY KEY (`id`),
  UNIQUE KEY `device_id` (`device_id`)
) ENGINE=InnoDB AUTO_INCREMENT=96 DEFAULT CHARSET=utf8mb4 COMMENT='lock';

the method findByDeviceId() is a spring data jpa interface method,just defining a method is enough.it's feature of spring data jpa, after called saveAndFlush() method,it send a sql like this: 方法findByDeviceId()是spring数据jpa接口方法,只需定义一个方法就足够了。它是spring数据jpa的功能,在调用saveAndFlush()方法之后,它会发送如下的sql:

Hibernate: insert into police_lock (create_time, is_deleted, device_id, name) values (?, ?, ?, ?)

and after the method excuted,the transaction was commited and the database generated the new record. 执行该方法后,将提交事务,数据库将生成新记录。 of course it's not generated before the method was excuted.but my question is that: thouth it's not commited,the modifying shoud be saw by following codes in the same transaction be it was not commited. 当然,它不是在执行该方法之前生成的。但是我的问题是: 尚未提交,如果未提交,则应在同一事务中遵循以下代码来查看修改内容。 but mine was not.i don't know why. 但是我不是。我不知道为什么。 . Am i missing something here? 我在这里想念什么吗?

my code is under spring boot,spring data jpa,mysql. 我的代码在spring boot下,spring data jpa,mysql。

i fixed it now, there is something wrong with my transaction configration,i modified it like as below: 我现在修复它,我的事务配置出了点问题,我如下修改了它:

@Configuration
public class TxConfig2 {
    @Autowired
    private PlatformTransactionManager transactionManager;

    @Bean(name = "txAdvice")
    public TransactionInterceptor getAdvisor() throws Exception {
        System.out.println("transactionManager = " + transactionManager);
        Properties properties = new Properties();
        properties.setProperty("init*", "PROPAGATION_REQUIRED,-Exception");
        properties.setProperty("add*", "PROPAGATION_REQUIRED,-Exception");
        properties.setProperty("insert*", "PROPAGATION_REQUIRED,-Exception");
        properties.setProperty("create*", "PROPAGATION_REQUIRED,-Exception");
        properties.setProperty("persist*", "PROPAGATION_REQUIRED,-Exception");
        properties.setProperty("update*", "PROPAGATION_REQUIRED,-Exception");
        properties.setProperty("modify*", "PROPAGATION_REQUIRED,-Exception");
        properties.setProperty("merge*", "PROPAGATION_REQUIRED,-Exception");
        properties.setProperty("bind*", "PROPAGATION_REQUIRED,-Exception");
        properties.setProperty("del*", "PROPAGATION_REQUIRED,-Exception");
        properties.setProperty("drop*", "PROPAGATION_REQUIRED,-Exception");
        properties.setProperty("remove*", "PROPAGATION_REQUIRED,-Exception");
        properties.setProperty("reset*", "PROPAGATION_REQUIRED,-Exception");
        properties.setProperty("cancel*", "PROPAGATION_REQUIRED,-Exception");
        properties.setProperty("login*", "PROPAGATION_REQUIRED,-Exception");
        properties.setProperty("save*", "PROPAGATION_REQUIRED,-Exception");
        properties.setProperty("update*", "PROPAGATION_REQUIRED,-Exception");
        properties.setProperty("delete*", "PROPAGATION_REQUIRED,-Exception");
        properties.setProperty("*", "PROPAGATION_REQUIRED,-Exception,readOnly");
        TransactionInterceptor tsi = new TransactionInterceptor(transactionManager, properties);
        return tsi;
    }
    @Bean
    public BeanNameAutoProxyCreator txProxy() {
        BeanNameAutoProxyCreator creator = new BeanNameAutoProxyCreator();
        creator.setInterceptorNames("txAdvice");
        creator.setBeanNames("*Service","*Dao");
        creator.setProxyTargetClass(true);
        return creator;
    }
}

then it works fine!!! 然后就可以了!!!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM