我正在尝试使用ASP Web服务和Oracle 10.2g数据库创建唯一策略。 我曾经有一个select查询和一个插入查询来创建策略号 但是昨天,Web服务是从2个不同的线程调用的,并且在相同的时间和两个相同的策略编号中创建。 所以我改变了代码以使用转换。 如果同时从两个不同的线程调用webservice,那么事务将如何工作? readcommited会阻止第二个线程,还是我会再遇到同样的问题? 选择查询是否有效或存在问题?
Public Function ExecutePolicyNumberTransaction(ByVal conet_key As String) As String
Dim policyno As String = ""
Dim sqlstring As String = ""
Dim conStr As String = ConfigurationManager.ConnectionStrings("con1").ConnectionString
Using connection As New OleDbConnection(conStr)
Dim transaction As OleDbTransaction
Try
connection.Open()
transaction = connection.BeginTransaction(IsolationLevel.ReadCommitted)
Dim insertcommand As New OleDbCommand()
insertcommand.Connection = connection
insertcommand.Transaction = transaction
sqlstring = " INSERT into POLICYNUMBERS ( " & _
" RECID, POLICYNO, REFERNCEKEY, ISUSED, ISUSEDDATE ) " & _
" (SELECT NVL(MAX(RECID),0)+1, concat('P0130',concat(to_char(SUBSTR('000000', 0, 6-length(to_char(NVL(MAX(RECID),0)+1)))),to_char(NVL(MAX(RECID),0)+1))), '" & ref_key & "', 1, sysdate " & _
" FROM POLICYNUMBERS )"
insertcommand.CommandText = sqlstring
insertcommand.ExecuteNonQuery()
transaction.Commit()
Dim selectcommand As New OleDbCommand()
selectcommand.Connection = connection
sqlstring = "SELECT POLICYNO FROM POLICYNUMBERS WHERE REFERNCEKEY = '" & ref_key & "'"
selectcommand.CommandText = sqlstring
policyno = selectcommand.ExecuteScalar()
Catch ex As Exception
Try
transaction.Rollback()
Catch
End Try
policyno = ""
End Try
End Using
Return policyno
End Function
答案 0 :(得分:1)
在Oracle中,读者不会阻止作者和作者不阻止读者。因此,两个会话都不会阻止另一个。
但是,在多用户环境中,除非特别引入某种形式的序列化,否则无法使用MAX(key)+1
生成主键。除非您想构建缓慢,不可靠的系统,否则您不希望引入序列化。相反,你真的,真的,真的想要使用一个序列来生成你的密钥。序列专门设计为以最小的开销为多个并发会话提供主键。
CREATE SEQUENCE policy_recid_seq
START WITH 1
INCREMENT BY 1
CACHE 100;
INSERT INTO policynumbers
SELECT policy_recid_seq.nextval, ...