V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
dust0522
V2EX  ›  Java

用了 ShardingSphere Spring Transactional 注解 改不了事务隔离级别

  •  
  •   dust0522 · 2023-02-21 09:45:33 +08:00 · 1254 次点击
    这是一个创建于 627 天前的主题,其中的信息可能已经有所发展或是发生改变。

    shardingsphere-jdbc 5.0.0 LOCAL Transaction

    Spring framework 5.2.12

    mysql 默认隔离级别 REPEATABLE-READ

    @Transactional(rollbackFor = Exception.class,isolation = Isolation.READ_UNCOMMITTED)

    我打断点 最后发现 spring 在处理这个判断的时候 因为 ShardingSphereConnection 默认的隔离级别预制了一个 TRANSACTION_READ_UNCOMMITTED

    if (definition != null && definition.getIsolationLevel() != TransactionDefinition.ISOLATION_DEFAULT) {}

    导致这行代码为 false

    有没有人遇见过,这个咋解决~

    spring 源码.

    ShardingSphereConnection.

    8 条回复    2023-02-22 14:36:21 +08:00
    dust0522
        1
    dust0522  
    OP
       2023-02-21 10:02:53 +08:00
    if (currentIsolation != definition.getIsolationLevel()) 应该是这个代码是 false 贴错了
    dust0522
        2
    dust0522  
    OP
       2023-02-21 10:04:56 +08:00
    WashFreshFresh
        3
    WashFreshFresh  
       2023-02-21 13:51:34 +08:00
    shardingjdbc 很多公司都是自己 fork 了自己玩自己的...
    dust0522
        4
    dust0522  
    OP
       2023-02-21 15:42:16 +08:00
    @WashFreshFresh 那我 fork 下来把 ShardingSphereConnection 默认的隔离级别预制成 REPEATABLE-READ 试试
    OldCarMan
        5
    OldCarMan  
       2023-02-21 23:03:51 +08:00
    可以不可以换种思路,通过 transactionManager 来设定你的事务隔离级别,大致代码如下:

    1. @Transactional(rollbackFor = Exception.class, transactionManager = "transactionManager")

    2.
    @Bean(name="transactionManager")
    public PlatformTransactionManager transactionManager((@Qualifier("entityManagerFactory") EntityManagerFactory entityManagerFactory){
    JpaTransactionManager jpaTransactionManager = new JpaTransactionManager();
    jpaTransactionManager.setEntityManagerFactory(entityManagerFactory);
    return jpaTransactionManager;
    }

    3.
    @Bean(name="entityManagerFactory")
    public EntityManagerFactory entityManager() {
    HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
    vendorAdapter.setDatabase(Database.MYSQL);
    vendorAdapter.setGenerateDdl(false);
    vendorAdapter.setShowSql(true);
    LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean();
    factory.setJpaVendorAdapter(vendorAdapter);
    factory.setDataSource(mysqlDataSource1());
    factory.afterPropertiesSet();
    return factory.getObject();
    }

    4.
    @Bean(name="mysqlDataSource1")
    @ConfigurationProperties(prefix="spring.datasource")
    public DataSource mysqlDataSource1() {
    return DataSourceBuilder.create().build();
    }

    5.
    配置文件里设置:spring.datasource.hikari.transaction-isolation=READ_UNCOMMITTED
    或者代码里自己设置 DataSourceProperty
    dust0522
        6
    dust0522  
    OP
       2023-02-22 11:47:46 +08:00
    @OldCarMan 你提醒了我,解决了哈哈,我用的 Druid 连接池 在配置文件中加入 spring.shardingsphere.datasource.defaultTransactionIsolation=4 (4 代表 REPEATABLE-READ), 这样连接池在创建连接的时候,会把这个值赋给 ShardingSphereConnection 。
    dust0522
        7
    dust0522  
    OP
       2023-02-22 11:56:52 +08:00
    spring.shardingsphere.datasource 利用反射初始化的连接池的创建参数,我一直没想连接池的事
    OldCarMan
        8
    OldCarMan  
       2023-02-22 14:36:21 +08:00
    @dust0522 很高兴看到你解决问题,如果你是多数据源,并同时要求多事务管理器的话,你可以参照我上面写的,如果你没有这要要求,那么你直接修改数据源的配置就行了,不用自定义事务管理器。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1128 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 20ms · UTC 23:40 · PVG 07:40 · LAX 15:40 · JFK 18:40
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.