tran.begin(TransactionPropagation.REQUIRES_NEW);提交时报错Transaction silently rolled back because it has been marked as rollback-only
时间: 2024-08-13 16:01:48 浏览: 80
这个错误通常发生在Spring框架中,当你试图在一个事务开始(`tran.begin(TransactionPropagation.REQUIRES_NEW)`)后立即提交,但是该事务已经被标记为只读或回滚(`rollback-only`),这时就会抛出异常。
`REQUIRES_NEW`是一个事务传播行为,它表示如果当前存在活跃事务,则会新建一个新的事务。然而,如果已有事务处于`readOnly`或`requiresRollback`状态,新的事务将无法正常创建,并会被隐式回滚,导致你在尝试提交时遇到错误。
这可能是由于之前某个地方的代码手动设置了事务为只读或者有异常发生后自动设置为了回滚。解决这个问题的方法包括:
1. 检查是否有代码无意中将事务设置为只读模式。
2. 确认所有业务操作都在事务范围内,特别是那些期望持久化变更的操作。
3. 如果你需要确保新事务不受影响,可以考虑使用其他事务传播行为,如`NEVER`或`REQUIRED`。
相关问题
SELECT * FROM sys.dm_tran_active_transactions 显示信息描述 Transaction_TYPE 2 信息怎么关闭
`sys.dm_tran_active_transactions` 是 SQL Server 中的一个系统视图,用于查询活动事务的信息。如果遇到 `Transaction_TYPE` 为 2 的事务(通常是死锁),你可以采取以下步骤来尝试解决并关闭它:
1. 确认死锁:查看该事务ID(TID),通常可以在 `transaction_id` 列中找到,然后通过如下的命令识别死锁涉及的资源:
```
SELECT *
FROM sys.dm_tran_locks
WHERE request_mode = 'X' AND request_status = 'WAIT'
AND transaction_sequence > (SELECT MAX(transaction_sequence) FROM sys.dm_tran_locks WHERE lock_session_id = <your_transaction_id>);
```
2. 解决死锁:作为拥有更高优先级的事务,可以尝试执行 `KILL` 命令结束死锁方的事务,例如:
```sql
KILL <deadlock_transaction_id>
```
或者如果是管理员权限,也可以尝试使用 `DBCC OPENTRAN` 和 `DBCC死了` 来手动解锁。
3. 避免死锁:检查应用程序是否按照正确的事务隔离级别运行,并避免长时间锁定资源。优化SQL查询和减少锁定范围也很重要。
4. 日志记录和监控:定期审查日志文件(如 SQL Server 错误日志),以便发现可能导致死锁的问题,并调整相关的数据库设置,比如增大 `max deadlock detection wait` 时间。
请注意,在实际操作中需要谨慎处理,因为直接杀死事务可能会导致数据一致性问题,最好是在了解情况并备份数据后再执行。
如何从字符串 "INSERT OVERWRITE TABLE HDQRY.TEMP_SZQQ2020_19072_XT SELECT T.tran_cusm_no ,'汇出' AS TRAN_TYPE FROM ORAMIS.CTIS_TXN_TIF_BAS_P_F T WHERE T.rel_payee_name REGEXP '信托' GROUP BY T.tran_cusm_no UNION ALL SELECT T.tran_cusm_no ,'汇入' AS TRAN_TYPE FROM ORAMIS.ctis_txn_tif_bas_p_f T WHERE T.rel_pay_name REGEXP '信托' GROUP BY T.tran_cusm_no ;--EOF|STEP-1(INSERT-HDQRY.TEMP_SZQQ2020_19072_XT OK)" 中匹配出 "SELECT T.tran_cusm_no ,'汇出' AS TRAN_TYPE FROM ORAMIS.CTIS_TXN_TIF_BAS_P_F T WHERE T.rel_payee_name REGEXP '信托' GROUP BY T.tran_cusm_no" 和 "SELECT T.tran_cusm_no ,'汇入' AS TRAN_TYPE FROM ORAMIS.ctis_txn_tif_bas_p_f T WHERE T.rel_pay_name REGEXP '信托' GROUP BY T.tran_cusm_no"
你可以使用正则表达式来匹配所需字符串。以下是匹配的正则表达式和代码:
```python
import re
s = "INSERT OVERWRITE TABLE HDQRY.TEMP_SZQQ2020_19072_XT SELECT T.tran_cusm_no ,'汇出' AS TRAN_TYPE FROM ORAMIS.CTIS_TXN_TIF_BAS_P_F T WHERE T.rel_payee_name REGEXP '信托' GROUP BY T.tran_cusm_no UNION ALL SELECT T.tran_cusm_no ,'汇入' AS TRAN_TYPE FROM ORAMIS.ctis_txn_tif_bas_p_f T WHERE T.rel_pay_name REGEXP '信托' GROUP BY T.tran_cusm_no ;--EOF|STEP-1(INSERT-HDQRY.TEMP_SZQQ2020_19072_XT OK)"
matches = re.findall(r"(SELECT\s+.*?GROUP\s+BY\s+\w+\.\w+)", s, re.IGNORECASE)
print(matches)
```
输出结果为:
```
["SELECT T.tran_cusm_no ,'汇出' AS TRAN_TYPE FROM ORAMIS.CTIS_TXN_TIF_BAS_P_F T WHERE T.rel_payee_name REGEXP '信托' GROUP BY T.tran_cusm_no", "SELECT T.tran_cusm_no ,'汇入' AS TRAN_TYPE FROM ORAMIS.ctis_txn_tif_bas_p_f T WHERE T.rel_pay_name REGEXP '信托' GROUP BY T.tran_cusm_no"]
```
解释一下正则表达式:
- `(SELECT\s+.*?GROUP\s+BY\s+\w+\.\w+)`: 匹配以SELECT开头,以GROUP BY加至少一个单词字符加一个点号加至少一个单词字符结尾的字符串,其中SELECT和GROUP BY可以是大小写混合的,且.*?表示非贪婪匹配,即尽可能少的匹配字符。`\s+`表示匹配至少一个空格,`\w+\.\w+`表示匹配一个或多个单词字符加一个点号加一个或多个单词字符。
希望这个代码对你有所帮助!