изменение не может быть видно в той же транзакции в весенних данных JPA, почему я получил нулевое значение после изменения в той же транзакции? - PullRequest
0 голосов
/ 23 ноября 2018

сначала покажите код, вот мой код, как показано ниже:

   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
    }

введите описание изображения здесь (вот скриншот)

я уверенчто метод 'saveTestTx ()' является полностью транзакцией, потому что если я вызвал print (22/0), его можно откатить.Я имею в виду, что коды от строки 192 до строки 199 находятся в одной транзакции.Исходя из своего опыта разработки на Java, я думаю, что lock2 - это результат lock1, я знаю, что до печати lock2 транзакция еще не зафиксирована, но они находятся в одной транзакции, видны изменения в той же транзакции, поэтомуперед выполнением транзакции его можно выбрать из вызванного метода «saveAndFlush ()», и оператор вставки будет напечатан на консоли, но на самом деле, почему в lock2 выводится ноль?

myКонфигурация транзакции выглядит следующим образом:

@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());
    }

}

мой код сущности выглядит следующим образом:

@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;
}

моя таблица выглядит следующим образом:

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';

метод findByDeviceId () является методом интерфейса jpa данных Spring, достаточно просто определить метод. Это свойство данных jpa пружины, после вызова метода saveAndFlush (), он отправляет sql следующим образом:

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

и после методаизвините, транзакция была зафиксирована, и база данных сгенерировала новую запись.конечно, он не был сгенерирован до того, как метод был оправдан. но мой вопрос таков: хотя он и не зафиксирован, модификация должна быть видна по следующим кодам в той же транзакции, если она не была зафиксирована.но мой не был. Я не знаю почему. .Я что-то здесь упускаю?

мой код находится под загрузкой пружины, данные пружины jpa, mysql.

1 Ответ

0 голосов
/ 24 ноября 2018

Я исправил это сейчас, что-то не так с моей конфигурацией транзакций, я изменил это, как показано ниже:

@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;
    }
}

тогда он работает нормально !!!

...