spring 事务不生效问题 bmw-jade-route事务配置

2023-05-16

在spring中配置了事务,但是没有生效

@Transactional(rollbackFor = {Exception.class})
    public Long insertTicket(Ticket ticket, List<Long> attachIds) throws Exception {
        LOGGER.info("Insert ticket with {}", ticket);
        ticket.setCreateAt(null);
        Long ticketId = ticketDao.insertTicket(ticket);
        LOGGER.info("Insert ticket {} success. Updating attachments {}", ticketId, attachIds == null ? "0" : attachIds.size());
        linkAttachmentsToTicket(ticketId, attachIds);
        List<String> arrTo = getSupervisorMailAddress(ticketId);
        LOGGER.info("Send notification email to biz type {} supervisors {}", ticket.getBizType(), arrTo == null ? "{null}" : arrTo.toString());
        sendEmailToOwner(ticketId, null, arrTo);
        return ticketId;
    }

该项目的数据源配置在zk中,使用Jade框架,后发现在applicationContext.xml中未配置事务:

<!-- 事务支持 -->
	<tx:annotation-driven transaction-manager="transactionManager"
		proxy-target-class="false" />
	<bean id="transactionManager"
		class="com.xxxx.dao.utils.TicketDataSourceTransactionManager">
		<property name="jadeDataSourceFactory" ref="jade.dataSourceFactory" />
		<property name="catalog" value="xxx" />
	</bean>
import javax.sql.DataSource;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import com.xiaomi.bmw.jade.route.database.DbRole;
import com.xiaomi.bmw.jade.route.database.JadeDataSourceFactory;

public class TicketDataSourceTransactionManager extends DataSourceTransactionManager {
    private String catalog;
    private JadeDataSourceFactory jadeDataSourceFactory;
    public TicketDataSourceTransactionManager() {
        super();
    }

    public TicketDataSourceTransactionManager(DataSource dataSource) {
        super(dataSource);
    }

    public void setJadeDataSourceFactory(JadeDataSourceFactory jadeDataSourceFactory) {
        this.jadeDataSourceFactory = jadeDataSourceFactory;
        this.tryBindDataSource();
    }

    public void setCatalog(String catalog) {
        this.catalog = catalog;
        this.tryBindDataSource();
    }

    private void tryBindDataSource() {
        if (null != this.catalog && null != this.jadeDataSourceFactory) {
            super.setDataSource(this.jadeDataSourceFactory.getDataSource(this.catalog, DbRole.MASTER, null));
        }
    }
}
import java.util.Map;

import javax.sql.DataSource;

import org.apache.commons.lang.Validate;
import org.apache.commons.lang3.StringUtils;
import org.springframework.jdbc.BadSqlGrammarException;
import org.springframework.transaction.support.TransactionSynchronizationManager;

import net.paoding.rose.jade.annotation.DAO;
import net.paoding.rose.jade.annotation.SQLType;
import net.paoding.rose.jade.annotation.UseMaster;
import net.paoding.rose.jade.statement.StatementMetaData;

import com.xiaomi.bmw.jade.route.annotation.UseMasterAndSlave;
import com.xiaomi.bmw.jade.route.database.DbRole;
import com.xiaomi.bmw.jade.route.database.JadeDataSourceFactory;

public class TicketDataSourceFactory extends JadeDataSourceFactory {
    private String defaultCatalog;

    @Override
    public DataSource getDataSource(StatementMetaData metaData, Map<String, Object> runtimeProperties) {
        Object shardValue = null;
        if (metaData.getShardByIndex() >= 0) {
            shardValue = getShardValue(metaData, runtimeProperties);
        }
        DAO dao = metaData.getMethod().getDeclaringClass().getAnnotation(DAO.class);
        String catalog = dao.catalog();
        if (StringUtils.isEmpty(catalog)) {
            catalog = this.defaultCatalog;
        }

        Validate.notEmpty(catalog, "catalog cannot be empty");
        DbRole dbRole = getDbRole(metaData);
        return getDataSource(catalog, dbRole, shardValue);
    }

    private DbRole getDbRole(StatementMetaData metaData) {
        DbRole dbRole = DbRole.MASTER;
        // 当前线程没有启动事务,才有下面的逻辑,否则直接用主库。
        if (!TransactionSynchronizationManager.isActualTransactionActive()) {
            SQLType sqlType = metaData.getSQLType();
            if (sqlType == SQLType.READ) {
                if (metaData.getMethod().isAnnotationPresent(UseMaster.class)) {
                    dbRole = DbRole.MASTER;
                } else if (metaData.getMethod().isAnnotationPresent(UseMasterAndSlave.class)) {
                    dbRole = DbRole.MASTERANDSLAVE;
                } else {
                    dbRole = DbRole.SLAVE;
                }
            }
        }

        return dbRole;
    }

    private Object getShardValue(StatementMetaData metaData, Map<String, Object> runtimeProperties) {
        if (metaData.getShardByIndex() < 0) {
            throw new BadSqlGrammarException("JadeDataSourceFactory.getShardValue@ShardByIndex < 0", "SQL [" + metaData.getSQL()
                    + "] shardByIndex: " + metaData.getShardByIndex(), null);
        }
        int shardByIndex = metaData.getShardByIndex() + 1;
        Object shardValue = runtimeProperties.get(":" + shardByIndex);
        if (shardValue == null) {
            throw new BadSqlGrammarException("JadeDataSourceFactory.getShardValue@ShardValue Not Found", "SQL [" + metaData.getSQL()
                    + "] Query without shard parameter: " + runtimeProperties, null);
        }
        return shardValue;
    }

    public void setDefaultCatalog(String catalog) {
        this.defaultCatalog = catalog;
    }

}

我引用的bmw-jade-route的版本为1.0

            <groupId>com.xiaomi</groupId>
            <artifactId>bmw-jade-route</artifactId>
            <version>1.0</version>

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

spring 事务不生效问题 bmw-jade-route事务配置 的相关文章

随机推荐