使用ReadCommited进行的事务可以阻止来自其他线程的选择吗?

时间:2014-10-24 12:42:54

标签: asp.net oracle10g

我正在尝试使用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

1 个答案:

答案 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, ...